package org.wu.framework.lazy.orm.database.jpa.repository.support.select;


import org.wu.framework.lazy.orm.database.jpa.repository.query.LazyQueryMetadata;
import org.wu.framework.lazy.orm.database.jpa.repository.support.AbstractLazySimpleQuerySupport;
import org.wu.framework.lazy.orm.database.lambda.domain.PersistenceRepository;
import org.wu.framework.lazy.orm.database.lambda.stream.lambda.LazyLambdaStream;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;

public class LazySimpleSelectQuerySupport extends AbstractLazySimpleQuerySupport {
    private final LazyQueryMetadata lazyQueryMetadata;

    public LazySimpleSelectQuerySupport(LazyQueryMetadata lazyQueryMetadata) {
        super(lazyQueryMetadata);
        this.lazyQueryMetadata = lazyQueryMetadata;
    }


    /**
     * 执行
     *
     * @return T
     */
    @Override
    protected <T> T doQuery() {

        LazyLambdaStream lazyLambdaStream = lazyQueryMetadata.getLazyLambdaStream();

        PersistenceRepository persistenceRepository = lazyQueryMetadata2PersistenceRepository(lazyQueryMetadata);


        // 返回结果是 List、Map、Bean
        Method queryMethod = lazyQueryMetadata.getQueryMethod();
        Type genericReturnType = queryMethod.getGenericReturnType();
        if (genericReturnType instanceof ParameterizedType parameterizedType) {
            // 结果是范型
            if (List.class.isAssignableFrom((Class<?>) parameterizedType.getRawType())) {
                Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
                Type actualTypeArgument = actualTypeArguments[0];
                if (actualTypeArgument instanceof ParameterizedType resultActualType && Map.class.isAssignableFrom((Class<?>) resultActualType.getRawType())) {
                    actualTypeArgument = Map.class;
                }
                persistenceRepository.setResultClass((Class<?>) actualTypeArgument);
                return (T) lazyLambdaStream.execute(persistenceRepository);
            } else if (Map.class.isAssignableFrom((Class<?>) parameterizedType.getRawType())) {
                persistenceRepository.setResultClass((Class<?>) parameterizedType.getRawType());
                return (T) lazyLambdaStream.executeOne(persistenceRepository);
            } else {
                // bean
                return (T) lazyLambdaStream.executeOne(persistenceRepository);
            }
        } else {
            // 结果不是范型
            Class<?> returnType = queryMethod.getReturnType();
            persistenceRepository.setResultClass(returnType);
            return (T) lazyLambdaStream.executeOne(persistenceRepository);
        }


    }
}
